#include <iostream>
#include <string>
using namespace std;
class Task 
{
public:
	Task() {}
	virtual ~Task() {}
	virtual void executeTask() = 0;
};

class FileTask : public Task
{
public:
	FileTask();
	virtual ~FileTask();
	virtual void executeTask();
	void readFile();
};

FileTask::FileTask()
{
    cout << "FileTask()" << endl;
}

FileTask::~FileTask()
{
    cout << "~FileTask()" << endl;
}

void FileTask::executeTask()
{
    cout << "FileTask::executeTask()" << endl;
}

void FileTask::readFile()
{
    cout << "FileTask::readFile()" << endl;
}

class DbTask : public Task
{
public:
	DbTask();
	virtual ~DbTask();
	virtual void executeTask();
	void readDatabase();
};

DbTask::DbTask()
{
    cout << "DbTask()" << endl;
}

DbTask::~DbTask()
{
    cout << "~DbTask()" << endl;
}

void DbTask::executeTask()
{
    cout << "DbTask::executeTask()" << endl;
}

void DbTask::readDatabase()
{
    cout << "DbTask::readDatabase()" << endl;
}

void doSomething(Task *p)
{
    p->executeTask();
    if(typeid(*p) == typeid(FileTask)) {
        FileTask *stu = dynamic_cast<FileTask*>(p);
        stu->readFile();
    }
    if(typeid(*p) == typeid(DbTask)) {
        DbTask *tea = dynamic_cast<DbTask*>(p);
        tea->readDatabase();
    }
}

int main()
{
    Task *ft = new FileTask;
    Task *dt = new DbTask;
    doSomething(ft);
    doSomething(dt);

    delete ft;
    ft = nullptr;
    delete dt;
    dt = nullptr;

    return 0;
}